import multiprocessing
from multiprocessing import Pool, Manager, Process
import os
import time
from threading import Thread

import gevent
from gevent import monkey


class MultiprocessingDemo:
    def work1(self):
        for i in range(3):
            nums.append(i)
            print('---work1---%s---' % nums)

    def work2(self):
        print('---work2---%s---' % nums)

    def work11(self, n):
        print('current work is %d, pid = %d' % (n, os.getpid()))
        time.sleep(0.5)

    def subproc(self, name, age, **kwargs):
        print('sub pid is %d' % os.getpid())
        while True:
            print('---subproc---name=%s---age=%d---kwargs=%s' % (name, age, kwargs))
            time.sleep(0.5)

    def write(self, queue):
        for i in range(10):
            queue.put_nowait(i)
            print('write %d' % i)

    def read(self, queue):
        while not queue.empty():
            print('read %d' % queue.get_nowait())

    def tfunc1(self, num):
        time.sleep(2)
        print('study' + str(num))

    def tfunc2(self, num):
        time.sleep(2)
        print('sleep' + str(num))

    def ptfunc1(self):
        t1_list = []
        for i in range(5):
            t1 = Thread(target=self.tfunc1, args=(i,))
            t1_list.append(t1)
        for t in t1_list:
            t.start()

    def ptfunc2(self):
        t2_list = []
        for i in range(5):
            t2 = Thread(target=self.tfunc2, args=(i,))
            t2_list.append(t2)
        for t in t2_list:
            t.start()

    def gfunc1(self, num1, num2):
        for i in range(5):
            print('study threading-no' + str(num1) + ' concurrent-no' + str(num2) + ' task-no' + str(i))
            time.sleep(2)

    def gfunc2(self, num1, num2):
        for i in range(5):
            print('sleep threading-no' + str(num1) + ' concurrent-no' + str(num2) + ' task-no' + str(i))
            time.sleep(2)

    def tgfunc1(self, num):
        g1_list = []
        for i in range(5):
            g1 = gevent.spawn(self.gfunc1, num, i)
            g1_list.append(g1)
        gevent.joinall(g1_list)

    def tgfunc2(self, num):
        g2_list = []
        for i in range(5):
            g2 = gevent.spawn(self.gfunc2, num, i)
            g2_list.append(g2)
        gevent.joinall(g2_list)

    def ptgfunc1(self):
        t1_list = []
        for i in range(5):
            t1 = Thread(target=self.tgfunc1, args=(i,))
            t1_list.append(t1)
        for t in t1_list:
            t.start()

    def ptgfunc2(self):
        t2_list = []
        for i in range(5):
            t2 = Thread(target=self.tgfunc2, args=(i,))
            t2_list.append(t2)
        for t in t2_list:
            t.start()

    def _test_globalvars(self):
        """
        md = MultiprocessingDemo()
        md._test_globalvars()
        """
        nums = [33, 44]
        p1 = multiprocessing.Process(target=self.work1)
        p2 = multiprocessing.Process(target=self.work2)
        p1.start()
        p1.join()
        p2.start()

    def _test_params(self):
        """
        md = MultiprocessingDemo()
        md._test_params()
        """
        print('current pid is %d' % os.getpid())
        p1 = multiprocessing.Process(target=self.subproc, args=('lizhen', 29), kwargs={'hha': 6})
        p1.start()
        while True:
            print('---main_proc---')
            time.sleep(1)

    def _test_pool(self):
        """
        md = MultiprocessingDemo()
        md._test_pool()
        """
        pool = Pool(3)
        for i in range(10):
            pool.apply_async(self.work11, (i,))
        pool.close()
        pool.join()
        print('---main_thread is over---')

    def _test_pool_queue(self):
        """
        md = MultiprocessingDemo()
        md._test_pool_queue()
        """
        print('---%s---start---' % os.getpid())
        q = Manager().Queue()
        pool = Pool(10)
        pool.apply_async(self.write, (q,))
        time.sleep(1)
        pool.apply_async(self.read, (q,))
        pool.close()
        pool.join()
        print('---%s---end---' % os.getpid())

    def _test_queue_nowait(self):
        """
        md = MultiprocessingDemo()
        md._test_queue_nowait()
        """
        q = multiprocessing.Queue(3)
        i = 0
        while not q.full():
            q.put_nowait('message%d' % i)
            i += 1

        while not q.empty():
            content = q.get_nowait()
            print('result--nowait--%s---' % content)

    def _test_queue(self):
        """
        md = MultiprocessingDemo()
        md._test_queue()
        """
        q = multiprocessing.Queue(3)
        i = 0
        while not q.full():
            q.put_nowait('message%d' % i)
            i += 1

        while not q.empty():
            content = q.get()
            print('result---%s---' % content)

    def _test_process_thread(self):
        """
        md = MultiprocessingDemo()
        md._test_process_thread()
        """
        p1 = Process(target=self.ptfunc1)
        p2 = Process(target=self.ptfunc2)
        p1.start()
        p2.start()
        while True:
            time.sleep(1)
            print('--main--')

    def _test_process_thread_gevent(self):
        """
        md = MultiprocessingDemo()
        md._test_process_thread_gevent()
        """
        # 打补丁
        monkey.patch_all()
        p1 = Process(target=self.ptgfunc1)
        p2 = Process(target=self.ptgfunc2)
        p1.start()
        p2.start()
        while True:
            time.sleep(0.5)
            print('--main--')


nums = [11, 22]

if __name__ == '__main__':
    md = MultiprocessingDemo()
    md._test_process_thread_gevent()
